﻿using FNN.Factories.SourcePoints;
using FNN.Helpers.IO;
using FNN.SourcePoints;
using System;
using System.Collections.Generic;
using System.Linq;

namespace FNN.Helpers.DataSource
{
    public class DataSourceHelper
    {
        private CsvHelper _csvHelper;
        private SourcePointFactory _factory;

        public DataSourceHelper(CsvHelper helper, SourcePointFactory factory)
        {
            _csvHelper = helper;
            _factory = factory;
        }

        /// <summary>
        ///     Преобразовать данные в массив точек
        /// </summary>
        /// <param name="headers">Заголовки</param>
        /// <param name="source">Содержимое</param>
        /// <returns>Массив точек</returns>
        protected IEnumerable<SourcePoint> ProcessData(IEnumerable<string> headers, IEnumerable<string[]> source)
        {
            var result = new List<SourcePoint>();
            foreach (var row in source)
            {
                var newPoint = _factory.CreatePoint(row[0]);
                for (var i = 1; i < row.ToList().Count(); i++)
                {
                    newPoint.Coordinates.Add(headers.ElementAt(i), Convert.ToDouble(row[i].Replace(".", ",")));
                }
                result.Add((SourcePoint)newPoint);
            }
            return result;
        }

        /// <summary>
        ///     Преобразовать данные в массив точек с задержкой
        /// </summary>
        /// <param name="headers">Заголовки</param>
        /// <param name="source">Содержимое</param>
        /// <param name="lag">Задержка</param>
        /// <returns>Массив точек</returns>
        protected IEnumerable<SourcePoint> ProcessData(IEnumerable<string> headers, IEnumerable<string[]> source, int lag)
        {
            var result = new List<SourcePoint>();
            for (int j = lag; j < source.Count(); j++)
            {
                var row = source.ElementAt(j);
                var laggedRow = source.ElementAt(j - lag);
                var newPoint = _factory.CreatePoint(row[0]);
                for (var i = 1; i < row.ToList().Count(); i++)
                {
                    newPoint.Coordinates.Add(headers.ElementAt(i), (Convert.ToDouble(row[i].Replace(".", ",")) / Convert.ToDouble(laggedRow[i].Replace(".", ","))) - 1);
                }
                result.Add((SourcePoint)newPoint);
            }
            return result;
        }

        public IEnumerable<SourcePoint> GetDataSource()
        {
            var dataHeaders = _csvHelper.GetHeader();
            var initialData = _csvHelper.GetBody();
            return ProcessData(dataHeaders, initialData);
        }
    }
}
